package com.software.usercenter.controller;

import cn.hutool.json.JSONObject;
import com.software.usercenter.domain.Result;
import com.software.usercenter.entity.Answer;
import com.software.usercenter.entity.RankUser;
import com.software.usercenter.entity.Record;
import com.software.usercenter.entity.User;
import com.software.usercenter.exception.BizException;
import com.software.usercenter.service.UserService;
import com.software.usercenter.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.*;


/**
 * Author: zk
 * Description: 用户控制层
 */
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    //注册的方法
    @PostMapping("/register")
    public Result register(@RequestBody User user){
        User register = userService.register(user);
        //返回回来说明没有抛异常 注册成功
        //如果该学号还没有被注册 返回注册成功
        return ResultUtil.success("200","注册成功",register);
    }

    //登录的方法
    @PostMapping("/login")
    public Result login(@RequestBody User user){
        User login = userService.login(user);
        //返回回来说明没有抛异常 登录成功
        return ResultUtil.success("200","登录成功",login);
    }

    //根据id查询用户信息
    @GetMapping("findUserById/{id}")
    public Result findUserById(@PathVariable String id){
        User user = userService.findUserById(id);
        return ResultUtil.success("200","查询用户信息成功",user);
    }
    //修改个人信息(性别、昵称)
    @PostMapping("/updateUserById")
    //个人信息和修改前是否一样 是否为空 由前端判断
    //后端只负责更改
    public Result updateUserById(@RequestBody User user){
        userService.updateUserById(user);
        return ResultUtil.success("200","修改个人信息成功",null);
    }
    //修改密码
    //密码和修改前是否一样 是否为空 由前端判断
    //后端只负责更改
    @PostMapping("/updatePassword")
    public Result updatePassword(@RequestBody User user){
        userService.updatePassword(user);
        return ResultUtil.success("200","修改密码成功",null);
    }
    //发布题解
    //交给question-center实现(王嘉欣写的方法)
    //用questionCenterFeign调用
    @PostMapping("/publishAnswer")
    public JSONObject publishAnswer(@RequestBody Answer answer){
        JSONObject insertAnswer=userService.publishAnswer(answer);
        return insertAnswer;
    }
    //查看题解列表(用分页查询)
    //交给question-center实现(王嘉欣写的方法)
    //用questionCenterFeign调用
    @GetMapping("/queryAnswerList")
    public JSONObject queryAnswerList(@RequestParam Integer questionId,
                                  @RequestParam(name="page",required = false,defaultValue = "1") Integer page,
                                  @RequestParam(name="size",required = false,defaultValue = "5")Integer size){
        if(page<1){
            throw new BizException("【查看题解列表】:当前页码不能小于1");
        }
        JSONObject pageResult=userService.queryAnswerList(questionId,page,size);
        return pageResult;
    }
    //查看具体题解
    //交给question-center实现(王嘉欣写的方法)
    //用questionCenterFeign调用
    @GetMapping("/queryAnswer/{answerId}")
    public JSONObject queryAnswer(@PathVariable String answerId){
        JSONObject queryAnswer = userService.queryAnswer(answerId);
        return queryAnswer;
    }
    //提交代码
    @PostMapping("/submitCode")
    public Result submitCode(@RequestBody Record record){
        // 评测代码, 然后再插入到record表中
        Record result = userService.insertRecord(record);
        return ResultUtil.success(result);
    }
    //查看答题记录列表(用分页查询)
    @GetMapping("/queryRecordList")
    public Result queryRecordList(String userId, Integer questionId,
                                  @RequestParam(name="page",required = false,defaultValue = "1") Integer page,
                                  @RequestParam(name="size",required = false,defaultValue = "10")Integer size){
        if(page<1){
            throw new BizException("【查看答题记录列表】:当前页码不能小于1");
        }
        //按照用户的答题时间排序  降序排列 后提交的记录在前面
        Sort.Order order=Sort.Order.desc("createTime");
        Sort sort=Sort.by(order);
        //都是从0开始 所以page-1
        Pageable pageable=PageRequest.of(page-1,size,sort);
        Page pageResult=userService.queryRecordList(userId, questionId,pageable);
        return ResultUtil.success("200","查询答题记录列表成功",pageResult);
    }
    //返回用户关于某个题的答题记录列表 不需要分页 不需要返回到浏览器
    @GetMapping("/queryOwnRecordList")
    public List<Record> queryRecordList(String userId, Integer questionId){
        List<Record> recordList = userService.queryOwnRecordList(userId, questionId);
        return recordList;
    }

    //查看某个具体答题记录
    @GetMapping("/queryRecord/{recordId}")
    public Result queryRecord(@PathVariable Integer recordId){
        Record queryRecord = userService.queryRecord(recordId);
        return ResultUtil.success(queryRecord);
    }



    //查看排行(用分页查询)
    @Cacheable(value = "cacheSpace",key = "#page")
    @GetMapping("/queryRank")
    public Result queryRank(User user,
                            @RequestParam(name="page",required = false,defaultValue = "1") Integer page,
                            @RequestParam(name="size",required = false,defaultValue = "10")Integer size){
        if(page<1){
            throw new BizException("【查看排行】:当前页码不能小于1");
        }
        //按照答题数排序 降序排序 答题多的在前面
        Sort.Order order=Sort.Order.desc("acCount");
        Sort sort=Sort.by(order);
        //都是从0开始 所以page-1
        Pageable pageable=PageRequest.of(page-1,size,sort);
        Page pageResult=userService.queryRank(pageable);
        return ResultUtil.success("200","查询排行成功",pageResult);
    }
    //清除排行缓存和个人排行缓存的方法
    @GetMapping("removeCache")
    @CacheEvict(value = "cacheSpace",allEntries = true)
    @Scheduled(cron = "0 */30 * * * ?")
    public void removeCache(){}

    //查询个人排行(缓存)
    @Cacheable(value = "cacheSpace",key = "#user.id")
    @GetMapping("queryOwnRank")
    public Result queryOwnRank(User user){
        RankUser rank = userService.queryOwnRank(user);
        return ResultUtil.success("200","查询个人排行成功",rank);
    }
}
